using System.Collections.Generic;
using Infragistics.Win.UltraWinGrid;

namespace ExperimentRuleEditor
{
	internal class GridDistinctCheckboxHelper
	{
		protected UltraGrid m_Grid;

		public UltraGrid Grid
		{
			get
			{
				return m_Grid;
			}
			set
			{
				if (m_Grid != value)
				{
					if (m_Grid != null)
					{
						OnControlDetached(m_Grid);
					}
					m_Grid = value;
					if (m_Grid != null)
					{
						OnControlAttached(m_Grid);
					}
				}
			}
		}

		public List<DistinctCheckBoxColumn> UniqueCheckboxColumns { get; protected set; }

		public GridDistinctCheckboxHelper(UltraGrid grid)
		{
			Grid = grid;
			UniqueCheckboxColumns = new List<DistinctCheckBoxColumn>();
		}

		protected void OnControlAttached(UltraGrid grid)
		{
			grid.BeforeCellUpdate += Grid_BeforeCellUpdate;
			grid.CellChange += grid_AfterCellUpdate;
		}

		protected void OnControlDetached(UltraGrid grid)
		{
			grid.BeforeCellUpdate -= Grid_BeforeCellUpdate;
			grid.CellChange -= grid_AfterCellUpdate;
		}

		private void Grid_BeforeCellUpdate(object sender, BeforeCellUpdateEventArgs e)
		{
			if (e.Cell.StyleResolved == ColumnStyle.CheckBox && IsColumnDistinctCheckBox(e.Cell.Column) && !IsNoCellCheckedAllowed(e.Cell.Column) && !(bool)e.NewValue && !IsBandContainsCheckedCell(e.Cell))
			{
				e.Cancel = true;
			}
		}

		private void grid_AfterCellUpdate(object sender, CellEventArgs e)
		{
			if (e.Cell.StyleResolved == ColumnStyle.CheckBox)
			{
				Grid.PerformAction(UltraGridAction.DeactivateCell);
			}
			if (e.Cell.StyleResolved == ColumnStyle.CheckBox && IsColumnDistinctCheckBox(e.Cell.Column))
			{
				ClearPreviouslyCheckedCells(e.Cell);
			}
		}

		protected bool IsColumnDistinctCheckBox(UltraGridColumn column)
		{
			return UniqueCheckboxColumns.Find((DistinctCheckBoxColumn c) => object.ReferenceEquals(c.CheckBoxColumn, column)) != null;
		}

		protected bool IsNoCellCheckedAllowed(UltraGridColumn column)
		{
			return UniqueCheckboxColumns.Find((DistinctCheckBoxColumn c) => object.ReferenceEquals(c.CheckBoxColumn, column) && c.AllowNoCellChecked) != null;
		}

		private bool IsBandContainsCheckedCell(UltraGridCell checkedCell)
		{
			foreach (UltraGridRow row in Grid.Rows)
			{
				foreach (UltraGridCell cell in row.Cells)
				{
					if (cell.Value.Equals(checkedCell.Value))
					{
						return true;
					}
				}
			}
			return false;
		}

		private void ClearPreviouslyCheckedCells(UltraGridCell checkedCell)
		{
			Grid.EventManager.SetEnabled(GridEventIds.BeforeCellUpdate, false);
			Grid.EventManager.SetEnabled(GridEventIds.AfterCellUpdate, false);
			foreach (UltraGridRow row in Grid.Rows)
			{
				foreach (UltraGridCell cell in row.Cells)
				{
					if (row != checkedCell.Row && cell.Value.Equals(checkedCell.Value))
					{
						cell.Value = false;
					}
				}
			}
			Grid.EventManager.SetEnabled(GridEventIds.BeforeCellUpdate, true);
			Grid.EventManager.SetEnabled(GridEventIds.AfterCellUpdate, true);
		}
	}
}
